package com.liming.common.coder.decoder;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONUtil;
import com.liming.common.enums.ResultEnum;
import com.liming.common.exception.BusinessException;
import com.liming.common.result.LMResult;
import feign.FeignException;
import feign.Response;
import feign.Util;
import feign.codec.Decoder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.lang.reflect.Type;

/**
 * @author liming
 * @date 2025/1/13
 */
@Slf4j
@RequiredArgsConstructor
public class FeignDecoder implements Decoder {

    @Override
    public Object decode(Response response, Type type) throws IOException, FeignException {
        log.info("泛型类型:{}", type);
        String bodyString = Util.toString(response.body().asReader(Util.UTF_8));
        log.info("bodyString:{}", bodyString);
        // 解析响应体字符串到 Result 对象
        LMResult<?> result = JSONUtil.toBean(bodyString, LMResult.class);
        log.info("LMResult对象:{}", result);
        // 如果响应状态为失败，抛出业务异常
        if (ResultEnum.ERROR.getCode().equals(result.getCode())) {
            throw new BusinessException(result.getMessage());
        }
        // 从 Result 中提取 data 字段
        Object resultData = result.getData();
        // 将 data 字段解析为指定类型的对象 工具类中已经存在null判断
        if (ObjectUtil.equal(Long.class, type)) {
            return Long.parseLong(resultData.toString());
        }
        try {
            if (ObjectUtil.isNotNull(resultData) && ObjectUtil.equal(resultData.getClass(), Boolean.class)
                    || ObjectUtil.isNotNull(resultData) && ObjectUtil.equal(resultData.getClass(), Integer.class)) {
                return resultData;
            }
            String resultDataJson = JSONUtil.toJsonStr(resultData);
            return JSONUtil.toBean(resultDataJson, type, false);
        } catch (JSONException e) {
            log.error("类型转换失败：{}", e.getMessage());
            log.error("resultData类型可能为包装类型");
            return resultData;
        }
    }


}

